#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
多目标优化示例

本示例演示如何使用MCP决策优化服务器的多目标优化功能，包括：
1. 创建多目标优化问题
2. 使用NSGA-II和MOEA/D算法求解
3. 分析帕累托前沿
4. 生成决策支持报告

作者: Decision Optimization Team
日期: 2024
"""

import sys
import os
sys.path.append(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))

from src.models import (
    DecisionVariable, ObjectiveFunction, Constraint, OptimizationProblem,
    VariableType, OptimizationType, ConstraintType, AlgorithmType
)
from src.multi_objective_engine import MultiObjectiveEngine

def create_multi_objective_problem():
    """
    创建一个经典的多目标优化问题：ZDT1测试函数
    
    目标函数：
    - f1(x) = x1
    - f2(x) = g(x) * h(f1, g)
    - g(x) = 1 + 9 * sum(x2...xn) / (n-1)
    - h(f1, g) = 1 - sqrt(f1/g)
    
    约束：
    - 0 <= xi <= 1 for all i
    """
    print("创建多目标优化问题...")
    
    # 创建决策变量 (30维)
    variables = []
    for i in range(30):
        var = DecisionVariable(
            name=f"x{i+1}",
            variable_type=VariableType.CONTINUOUS,
            lower_bound=0.0,
            upper_bound=1.0,
            description=f"决策变量 x{i+1}"
        )
        variables.append(var)
    
    # 创建目标函数
    objective1 = ObjectiveFunction(
        name="f1",
        expression="x1",  # 简化表达式，实际计算在引擎中实现
        optimization_type=OptimizationType.MINIMIZE,
        weight=1.0,
        description="第一个目标函数 f1(x) = x1"
    )
    
    objective2 = ObjectiveFunction(
        name="f2",
        expression="g * (1 - sqrt(x1/g))",  # 简化表达式
        optimization_type=OptimizationType.MINIMIZE,
        weight=1.0,
        description="第二个目标函数 f2(x) = g(x) * h(f1, g)"
    )
    
    # 创建约束条件
    constraints = []
    for i in range(30):
        constraint = Constraint(
            name=f"bound_x{i+1}",
            expression=f"0 <= x{i+1} <= 1",
            constraint_type=ConstraintType.INEQUALITY,
            description=f"变量 x{i+1} 的边界约束"
        )
        constraints.append(constraint)
    
    # 创建优化问题
    problem = OptimizationProblem(
        name="ZDT1_MultiObjective",
        variables=variables,
        objectives=[objective1, objective2],
        constraints=constraints,
        description="ZDT1多目标测试函数"
    )
    
    print(f"✓ 创建了包含 {len(variables)} 个变量和 {len(problem.objectives)} 个目标的优化问题")
    return problem

def solve_with_nsga_ii(engine, problem):
    """
    使用NSGA-II算法求解多目标优化问题
    """
    print("\n使用NSGA-II算法求解...")
    
    result = engine.optimize(
        problem=problem,
        algorithm_type=AlgorithmType.NSGA_II,
        population_size=100,
        max_generations=250,
        crossover_prob=0.9,
        mutation_prob=0.1
    )
    
    print(f"✓ NSGA-II优化完成")
    print(f"  - 帕累托解数量: {len(result.pareto_front)}")
    print(f"  - 超体积指标: {result.hypervolume:.4f}")
    print(f"  - 间距指标: {result.spacing:.4f}")
    print(f"  - 执行时间: {result.execution_time:.2f}秒")
    
    return result

def solve_with_moea_d(engine, problem):
    """
    使用MOEA/D算法求解多目标优化问题
    """
    print("\n使用MOEA/D算法求解...")
    
    result = engine.optimize(
        problem=problem,
        algorithm_type=AlgorithmType.MOEA_D,
        population_size=100,
        max_generations=250,
        crossover_prob=0.9,
        mutation_prob=0.1
    )
    
    print(f"✓ MOEA/D优化完成")
    print(f"  - 帕累托解数量: {len(result.pareto_front)}")
    print(f"  - 超体积指标: {result.hypervolume:.4f}")
    print(f"  - 间距指标: {result.spacing:.4f}")
    print(f"  - 执行时间: {result.execution_time:.2f}秒")
    
    return result

def analyze_results(engine, result):
    """
    分析优化结果
    """
    print("\n分析帕累托前沿...")
    
    analysis = engine.analyze_pareto_front(result)
    
    if "error" not in analysis:
        print(f"✓ 帕累托前沿分析完成")
        print(f"  - 解的数量: {analysis['solution_count']}")
        print(f"  - 超体积指标: {analysis['hypervolume']:.4f}")
        print(f"  - 间距指标: {analysis['spacing']:.4f}")
        
        print("\n目标函数范围:")
        for obj_name, ranges in analysis['objective_ranges'].items():
            print(f"  {obj_name}:")
            print(f"    最小值: {ranges['min']:.4f}")
            print(f"    最大值: {ranges['max']:.4f}")
            print(f"    平均值: {ranges['mean']:.4f}")
    else:
        print(f"✗ 分析失败: {analysis['error']}")

def generate_decision_support(engine, result):
    """
    生成决策支持
    """
    print("\n生成决策支持...")
    
    # 不指定权重偏好
    support = engine.generate_decision_support(result)
    
    if "error" not in support:
        print(f"✓ 决策支持生成完成")
        
        # 显示推荐解
        print("\n推荐解决方案:")
        for i, sol in enumerate(support['recommended_solutions'][:3], 1):
            print(f"\n推荐方案 {i}:")
            print("  目标函数值:")
            for obj_name, obj_value in sol.objective_values.items():
                print(f"    {obj_name}: {obj_value:.4f}")
        
        # 显示权衡分析
        if support['trade_off_analysis']:
            print("\n目标函数权衡分析:")
            for comparison, correlation in support['trade_off_analysis'].items():
                print(f"  {comparison}: 相关性 = {correlation:.3f}")
                if correlation < -0.5:
                    print(f"    → 强负相关，存在明显权衡")
                elif correlation > 0.5:
                    print(f"    → 强正相关，目标一致")
                else:
                    print(f"    → 弱相关，权衡不明显")
    else:
        print(f"✗ 决策支持生成失败: {support['error']}")

def compare_algorithms(result1, result2):
    """
    比较两种算法的性能
    """
    print("\n算法性能比较:")
    print(f"NSGA-II vs MOEA/D")
    print(f"帕累托解数量: {len(result1.pareto_front)} vs {len(result2.pareto_front)}")
    print(f"超体积指标: {result1.hypervolume:.4f} vs {result2.hypervolume:.4f}")
    print(f"间距指标: {result1.spacing:.4f} vs {result2.spacing:.4f}")
    print(f"执行时间: {result1.execution_time:.2f}s vs {result2.execution_time:.2f}s")
    
    # 判断哪个算法更优
    if result1.hypervolume > result2.hypervolume:
        print("→ NSGA-II在超体积指标上更优")
    elif result2.hypervolume > result1.hypervolume:
        print("→ MOEA/D在超体积指标上更优")
    else:
        print("→ 两种算法在超体积指标上相当")

def main():
    """
    主函数：演示多目标优化的完整流程
    """
    print("=" * 60)
    print("MCP决策优化服务器 - 多目标优化示例")
    print("=" * 60)
    
    try:
        # 1. 创建多目标优化问题
        problem = create_multi_objective_problem()
        
        # 2. 初始化多目标优化引擎
        engine = MultiObjectiveEngine()
        
        # 3. 使用NSGA-II算法求解
        nsga_result = solve_with_nsga_ii(engine, problem)
        
        # 4. 使用MOEA/D算法求解
        moea_result = solve_with_moea_d(engine, problem)
        
        # 5. 分析NSGA-II结果
        print("\n" + "=" * 40)
        print("NSGA-II结果分析")
        print("=" * 40)
        analyze_results(engine, nsga_result)
        generate_decision_support(engine, nsga_result)
        
        # 6. 分析MOEA/D结果
        print("\n" + "=" * 40)
        print("MOEA/D结果分析")
        print("=" * 40)
        analyze_results(engine, moea_result)
        generate_decision_support(engine, moea_result)
        
        # 7. 比较两种算法
        print("\n" + "=" * 40)
        print("算法比较")
        print("=" * 40)
        compare_algorithms(nsga_result, moea_result)
        
        print("\n" + "=" * 60)
        print("多目标优化示例完成！")
        print("=" * 60)
        
    except Exception as e:
        print(f"\n✗ 示例执行失败: {str(e)}")
        import traceback
        traceback.print_exc()

if __name__ == "__main__":
    main()